<template>
  <div class="employees-container">
    <div class="app-container">
      <!-- 通用工具栏组件使用 -->
      <page-tools>
        <!-- 自定义左侧内容 -->
        <template #slot-left>
          <span>共19条记录</span>
        </template>

        <!-- 自定义右侧内容 -->
        <template #slot-right>
          <el-button
            v-power="'import'"
            type="danger"
            size="small"
            @click="imExcelFn"
            >导入excel</el-button
          >
          <el-button
            v-power="'export'"
            type="success"
            size="small"
            @click="ExportbtnFn"
            >导出excel</el-button
          >
          <el-button type="primary" size="small" @click="addEmpShowDialogFn"
            >新增员工</el-button
          >
        </template>
      </page-tools>

      <el-card style="margin-top: 10px;">
        <el-table border :data="employeesList">
          <el-table-column type="index" label="序号" />
          <el-table-column prop="username" label="姓名" />
          <el-table-column prop="staffPhoto" label="头像">
            <template v-slot="{ row }">
              <image-holder class="staffPhoto" :src="row.staffPhoto" alt="" />
            </template>
          </el-table-column>
          <el-table-column prop="mobile" label="手机号" />
          <el-table-column
            prop="workNumber"
            label="工号"
            sortable
            :sort-method="workNumberSortFn"
          />
          <!-- sort-method:对数据进行排序的时候使用的方法，仅当 sortable 设置为 true 的时候有效，需返回一个数字，和 Array.sort 表现一致 -->
          <el-table-column prop="formOfEmployment" label="聘用形式">
            <!-- (1): 使用插槽技术时, (2): 需要组件内变量 -> 作用域插槽
              作用域插槽:
                (1): 在组件内, 用<slot 属性名="组件内变量值"></slot> (table-column写好了内部叫row)
                (2): 在插槽内, 用template v-slot="变量名" (变量会收集slot身上属性和值形成对象)

              条件表达式(只能用于 true和false, 如果有第三种情况)

             -->
            <template v-slot="scope">
              <span>{{ formatter(scope.row) }}</span>
            </template>
          </el-table-column>
          <el-table-column prop="departmentName" label="部门" />

          <el-table-column
            prop="timeOfEntry"
            label="入职时间"
            :formatter="timeFormatter"
          />

          <el-table-column label="操作" width="280">
            <template v-slot="{ row }">
              <el-button type="text" size="small" @click="lookFn(row)"
                >查看</el-button
              >
              <el-button type="text" size="small" @click="roleFn(row)"
                >分配角色</el-button
              >
              <el-button type="text" size="small" @click="delrole(row)"
                >删除</el-button
              >
            </template>
          </el-table-column>
        </el-table>
        <!-- 分页组件 -->
        <el-row type="flex" justify="end" align="middle" style="height: 60px">
          <!-- 分页区域 -->
          <el-pagination
            :current-page="query.page"
            :page-sizes="[5, 15, 20, 25]"
            :page-size="query.size"
            layout="total, sizes, prev, pager, next, jumper"
            :total="total"
            @size-change="handleSizeChange"
            @current-change="handleCurrentChange"
          />
        </el-row>
      </el-card>

      <el-dialog @close="closefn" title="添加员工" :visible.sync="showDialog">
        <emp-form
          ref="empForm"
          @addEmev="addEmev"
          :show.sync="showDialog"
          :treeData="treeData"
        ></emp-form>
      </el-dialog>
      <!-- 员工-分配角色-弹框 -->
      <el-dialog :visible.sync="showRoleDialog">
        设置角色组件
        <assign-role
          ref="assignRoleDialog"
          :allRoleList="allRoleList"
          :show.sync="showRoleDialog"
          @addRoleEv="addRoleFn"
        />
      </el-dialog>
    </div>
  </div>
</template>

<script>
import empForm from './components/empForm.vue'
import dayjs from 'dayjs'

import {
  getEmployeesListAPI,
  companyDepartment,
  delEmployeeAPI,
  addEmployeesAPI,
  getRolesAPI,
  sysUser,
  saveEmployeesRoleAPI
} from '@/api'
import Employees from '@/api/constant'
import { transTree } from '@/utils'
import AssignRole from './components/assignRoleDialog.vue'

export default {
  name: 'Employees',
  components: {
    empForm,
    AssignRole
  },
  data () {
    return {
      query: {
        page: 1, // 页码
        size: 5 // 每页条数
      },
      employeesList: [], // 员工列表
      total: 0, // 数据总条数
      showDialog: false, // 新增弹窗开关
      treeData: [], // 公司部门列表
      allemployeesList: [], // 所以员工数据数组
      showRoleDialog: false, // 分配角色弹框
      allRoleList: [], // 所有角色列表
      clickId: '' // 点击行的id
    }
  },
  created () {
    this.getEmployeesListfn() // 获取员工列表
    this.companyDepartmentfn() // 获取部门列表
    this.getRolesFn() // 获取所有角色列表
  },
  methods: {
    // 获取员工列表
    async getEmployeesListfn () {
      const res = await getEmployeesListAPI(this.query)
      // console.log(res)
      this.employeesList = res.data.rows
      // console.log(this.employeesList)
      this.total = res.data.total
      // 第二次请求,拿到所有数据
      const allRes = await getEmployeesListAPI({
        page: 1,
        size: res.data.total
      })
      this.allemployeesList = allRes.data.rows
    },
    // 获取公司部门列表
    async companyDepartmentfn () {
      const res = await companyDepartment()

      this.treeData = transTree(res.data.depts, '')
    },
    // 获取所有角色列表
    async getRolesFn () {
      const res = await getRolesAPI({
        page: 1,
        size: 10
      })
      const res1 = await getRolesAPI({
        page: 1,
        size: res.data.total
      })

      this.allRoleList = res1.data.rows
    },
    // 聘用格式,数据处理
    formatter (row) {
      const obj = Employees.hireType.find(
        item => item.id === parseInt(row.formOfEmployment)
      )
      return obj ? obj.value : '未知'
    },
    // 时间格式,数据处理
    timeFormatter (row) {
      return dayjs(row.timeOfEntry).format('YYYY-MM-DD')
    },

    // 工号->排序方法
    // 数组的sort方法: https://developer.mozilla.org/zh-CN/docs/Web/JavaScript/Reference/Global_Objects/Array/sort
    workNumberSortFn (a, b) {
      return parseInt(a.workNumber) - parseInt(b.workNumber)
    },
    // 新增员工
    addEmpShowDialogFn () {
      this.showDialog = true
    },
    // 删除员工
    async delrole (row) {
      const delRes = await this.$confirm(
        '此操作将永久删除该角色,是否继续?',
        '温馨提示',
        {
          confirmButtonText: '确定',
          cancelButtonText: '取消',
          type: 'warning'
        }
      ).catch(err => err)
      if (delRes === 'cancel') {
        this.$message.info('您取消了操作')
      } else {
        const res = await delEmployeeAPI(row.id)
        this.$message.success(res.message)
        this.getEmployeesListfn() // 获取员工列表
      }
    },
    // 每页显示的条数发生改变时触发
    handleSizeChange (newSize) {
      this.query.size = newSize
      this.getEmployeesListfn() // 获取员工列表
    },

    // 当前页面发生改变时触发
    handleCurrentChange (newPage) {
      this.query.page = newPage
      this.getEmployeesListfn() // 获取员工列表
    },
    // 新增员工
    async addEmev (formData) {
      const res = await addEmployeesAPI(formData)
      this.$message.success(res.message)
      this.getEmployeesListfn() // 获取员工列表
    },
    closefn () {
      this.$refs.empForm.$refs.form.resetFields()
    },
    // 点击导入跳转页面
    imExcelFn () {
      this.$router.push('/excel')
    },
    //导出excel
    ExportbtnFn () {
      import('@/vendor/Export2Excel').then(excel => {
        const tHeader = [
          '序号',
          '姓名',
          '头像',
          '手机号',
          '工号',
          '聘用形式',
          '部门',
          '入职时间'
        ]

        // const newArr = this.employeesList.map(obj => {
        //   return Object.values(obj)
        // })
        // 1. 中文->英文的映射关系(枚举值)
        // 序号在遍历的时候,就有索引值了,所以它的值不用去英文对象里获取,所以不用映射
        const myObj = {
          // 序号可以等遍历的时候直接用索引值, 而不是来自于英文对象里
          姓名: 'username',
          头像: 'staffPhoto',
          手机号: 'mobile',
          工号: 'workNumber',
          聘用形式: 'formOfEmployment',
          部门: 'departmentName',
          入职时间: 'timeOfEntry'
        }
        // 2.遍历每个英文对象
        const data = this.allemployeesList.map((enObj, index) => {
          // 3.遍历每个中文对象的key值
          const newArr = []
          tHeader.forEach(zhkey => {
            if (zhkey === '序号') {
              newArr.push(index + 1)
            } else {
              const enkey = myObj[zhkey]
              const value = enObj[enkey]
              if (enkey === 'formOfEmployment') {
                // 用映射判断聘用形式
                const obj = Employees.hireType.find(
                  item => item.id === parseInt(value)
                )
                newArr.push(obj ? obj.value : '未知')
              } else {
                newArr.push(value)
              }
            }
          })
          // 4.把每一行值数组return给map
          // console.log(newArr)

          return newArr
        })
        //  export_json_to_excel()方法是vendor/Export2Excel.js文件内封装的导出excel文件的方法
        excel.export_json_to_excel({
          // excel第一行标题
          header: tHeader,
          // 表格里第二行开始的正文数据
          data,
          // 导出时excel文件的名字(无需写后缀)
          filename: '',
          // 单元格宽度的自适应
          autoWidth: true,
          bookType: 'xlsx'
        })
      })
    },
    // 跳转页面传参
    lookFn (row) {
      this.$router.push(
        `/employees/detail?id=${row.id}&form=${row.formOfEmployment}`
      )
    },
    // 点击分配角色
    async roleFn (row) {
      const res = await sysUser(row.id)
      this.clickId = row.id
      this.showRoleDialog = true
      console.log(res)
      console.log(res.data.roleIds)
      this.$nextTick(() => {
        this.$refs.assignRoleDialog.roleIdsList = res.data.roleIds || []
      })
      // setTimeout(() => {
      //   this.$refs.assignRoleDialog.roleIdsList = res.data.roleIds || []
      // }, 0)
    },
    // 点击确定分配角色
    async addRoleFn (roleIdsList) {
      const res = await saveEmployeesRoleAPI({
        id: this.clickId,
        roleIds: roleIdsList
      })
      this.$message.success(res.message)
      console.log(res)
      // this.getEmployeesListfn() // 获取员工列表
    }
  }
}
</script>

<style lang="scss" scoped>
.staffPhoto {
  width: 100px;
  height: 100px;
  border-radius: 50%;
}
</style>
